﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web;

namespace Besture.Utils
{
    public class SessionUtil
    {
        /// <summary>
        /// 获取Session
        /// </summary>
        /// <param name="sessionKey"></param>
        /// <returns></returns>
        public static object GetSession(string sessionKey)
        {
            return HttpContext.Current.Session[sessionKey];
        }
        /// <summary>
        /// 设置session
        /// </summary>
        /// <param name="sessionKey"></param>
        /// <param name="sessionObject"></param>
        public static void SetSession(string sessionKey, object sessionObject)
        {
            HttpContext.Current.Session.Remove(sessionKey);
            HttpContext.Current.Session.Add(sessionKey, sessionObject);
            // SetSession(sessionKey, sessionObject);
        }
        /// <summary>
        /// 设置session
        /// </summary>
        /// <param name="sessionKey"></param>
        /// <param name="sessionObject"></param>
        /// <param name="expires"></param>
        public static void SetSession(string sessionKey, object sessionObject, int expires)
        {
            HttpContext.Current.Session.Remove(sessionKey);
            HttpContext.Current.Session.Add(sessionKey, sessionObject);
            HttpContext.Current.Session.Timeout = expires;
        }
        /// <summary>
        /// 设置session
        /// </summary>
        /// <param name="sessionKey"></param>
        /// <param name="sessionValue"></param>
        /// <param name="expires"></param>
        public static void SetSession(string sessionKey, string sessionValue, int expires)
        {
            HttpContext.Current.Session.Remove(sessionKey);
            HttpContext.Current.Session.Add(sessionKey, sessionValue);
            HttpContext.Current.Session.Timeout = expires;

        }
        /// <summary>
        /// 设置session
        /// </summary>
        /// <param name="sessionKey">session 名</param>
        /// <param name="sessionValue">session 值</param>
        public static void SetSession(string sessionKey, string sessionValue)
        {
            HttpContext.Current.Session.Remove(sessionKey);
            HttpContext.Current.Session.Add(sessionKey, sessionValue);
            //SetSession(sessionKey, sessionValue);
        }
        /// <summary>
        /// 删除一个指定的ession
        /// </summary>
        /// <param name="sessionKey">Session名称</param>
        /// <returns></returns>
        public static void RemoveSession(string sessionKey)
        {
            HttpContext.Current.Session.Remove(sessionKey);
        }
        /// <summary>
        /// 删除所有的ession
        /// </summary>
        /// <returns></returns>
        public static void RemoveSession()
        {
            HttpContext.Current.Session.RemoveAll();
        }


        #region 最近浏览

        public static DataTable GetRecentlyViewedProduct(RecentlyViewedProductModel model)
        {

            const string RecentlyViewedkey = "RecentlyViewedkey";
            List<RecentlyViewedProductModel> listRecentlyViewedProductModel = GetSession(RecentlyViewedkey) as List<RecentlyViewedProductModel>;
            if (listRecentlyViewedProductModel == null)
            {
                if (model != null)
                {
                    model.no = DateTime.Now.ToString("yyyyMMddHHmmss");
                    listRecentlyViewedProductModel = new List<RecentlyViewedProductModel>();
                    listRecentlyViewedProductModel.Add(model);
                }
                SetSession(RecentlyViewedkey, listRecentlyViewedProductModel);
                return null;
            }
            else
            {
                int index = -1;
                for (int i = 0; i < listRecentlyViewedProductModel.Count; i++)
                {
                    if (model != null && listRecentlyViewedProductModel[i].id == model.id)
                    {
                        index = i;
                        break;
                    }
                }

                if (index > -1)
                {
                    listRecentlyViewedProductModel.RemoveAt(index);
                }
                if (listRecentlyViewedProductModel.Count > 6)
                {
                    listRecentlyViewedProductModel.RemoveAt(0);
                }
                if (model != null)
                {
                    listRecentlyViewedProductModel.Add(model);
                }
                List<RecentlyViewedProductModel> returnListRecentlyViewedProductModel = listRecentlyViewedProductModel.OrderByDescending(m => m.no).ToList();
                SetSession(RecentlyViewedkey, listRecentlyViewedProductModel);
                return ToDataTable(returnListRecentlyViewedProductModel);
            }
        }

        /// <summary>
        /// Convert a List{T} to a DataTable.
        /// </summary>
        private static DataTable ToDataTable<T>(IEnumerable<T> items)
        {
            var tb = new DataTable(typeof(T).Name);

            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo prop in props)
            {
                Type t = GetCoreType(prop.PropertyType);
                tb.Columns.Add(prop.Name, t);
            }

            foreach (T item in items)
            {
                var values = new object[props.Length];

                for (int i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                }

                tb.Rows.Add(values);
            }

            return tb;
        }

        /// <summary>
        /// Determine of specified type is nullable
        /// </summary>
        public static bool IsNullable(Type t)
        {
            return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
        }

        /// <summary>
        /// Return underlying type if type is Nullable otherwise return the type
        /// </summary>
        public static Type GetCoreType(Type t)
        {
            if (t != null && IsNullable(t))
            {
                if (!t.IsValueType)
                {
                    return t;
                }
                else
                {
                    return Nullable.GetUnderlyingType(t);
                }
            }
            else
            {
                return t;
            }
        }

        #endregion
    }

    /// <summary>
    /// 最近浏览
    /// </summary>
    public class RecentlyViewedProductModel
    {
        public string no { get; set; }
        public string id { get; set; }
        public string name { get; set; }
        public string imageUrl { get; set; }
    }
}
